package evaluate;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.sql.DriverManager;
import java.util.HashSet;

import com.mysql.jdbc.Connection;
import com.mysql.jdbc.ResultSet;
import com.mysql.jdbc.Statement;

public class HitRate {

	private Connection conn;
	private Statement stmt = null;
	private ResultSet rs = null;
	private int topN = 10;

	public HitRate() throws Exception {
		Class.forName("com.mysql.jdbc.Driver").newInstance();
		String url = "jdbc:mysql://localhost:3306/" + "bibsonomy";
		String dbuser = "root";
		String dbpass = "123456";
		Connection con = (Connection) DriverManager.getConnection(url, dbuser,
				dbpass);
		this.conn = con;

	}

	private HashSet<String> extractTas(String user, String item)
			throws Exception {
		rs = (ResultSet) stmt
				.executeQuery("SELECT tag FROM TAS_NEW where user = '" + user
						+ "' and content_id = '" + item + "'");
		HashSet<String> tags = new HashSet<String>();
		while (rs.next()) {
			String tag = rs.getString("tag");
			tags.add(tag);
		}
		return tags;
	}

	public void run(String metric) throws Exception {
		stmt = (Statement) conn.createStatement();
		String path = "D:\\CityU\\project\\bibsonomy\\experiment\\";
		File root = new File(path);
		File[] list = root.listFiles();
		// double score = 0.0;
		String res = "D:\\CityU\\project\\bibsonomy\\evaluate\\hitrate_"
				+ metric + ".txt";
		BufferedWriter writer = new BufferedWriter(new FileWriter(res));
		try {
			for (File file : list) {
				String user = file.getName();
				double userScore = 0.0;
				File userFile = new File(file, "result\\" + metric + "\\");
				File[] itemFiles = userFile.listFiles();
				for (File itemFile : itemFiles) {
					String n = itemFile.getName();
					int idx = n.indexOf(".txt");
					String item = n.substring(0, idx);
					HashSet<String> tags = extractTas(user, item);
					HashSet<String> results = retrieveResults(itemFile);
					userScore = userScore + calUnit(tags, results);
				}
				userScore = userScore / itemFiles.length;
				System.out.println(user + "\t" + userScore);
				writer.write(user + "\t" + userScore);
				writer.newLine();
			}
		} finally {
			writer.flush();
			writer.close();
		}
	}

	public void runHybrid(String metric, int step) throws Exception {

		String path = "D:\\CityU\\project\\bibsonomy\\experiment\\";
		File root = new File(path);
		File[] list = root.listFiles();
		String res = "D:\\CityU\\project\\bibsonomy\\evaluate\\hitrate_"
				+ metric + "_" + step + ".txt";
		BufferedWriter writer = new BufferedWriter(new FileWriter(res));
		try {
			for (File file : list) {

				String user = file.getName();
				double userScore = 0.0;
				File userFile = new File(file, "result\\" + metric + "\\"
						+ step + "\\");
				File[] itemFiles = userFile.listFiles();
				for (File itemFile : itemFiles) {
					String n = itemFile.getName();
					int idx = n.indexOf(".txt");
					String item = n.substring(0, idx);
					HashSet<String> tags = extractTas(user, item);
					HashSet<String> results = retrieveResults(itemFile);
					userScore = userScore + calUnit(tags, results);
				}
				userScore = userScore / itemFiles.length;
				System.out.println(user + "\t" + userScore + "\tstep\t" + step);
				writer.write(user + "\t" + userScore);
				writer.newLine();

			}
		} finally {
			writer.flush();
			writer.close();
		}

	}

	private void initStmt() throws Exception {
		stmt = (Statement) conn.createStatement();
	}

	private HashSet<String> retrieveResults(File file) throws Exception {
		BufferedReader reader = new BufferedReader(new FileReader(file));
		String line = null;
		HashSet<String> results = new HashSet<String>();
		int cnt = 0;
		while ((line = reader.readLine()) != null) {
			if (cnt == topN)
				break;
			line = line.trim();
			String[] tokens = line.split("\t");
			results.add(tokens[0]);
			cnt++;
		}
		return results;
	}

	private double calUnit(HashSet<String> tags, HashSet<String> results) {
		double score = 0.0;
		for (String result : results) {
			if (tags.contains(result)) {
				score++;
			}
		}
		score = score / tags.size();
		return score;
	}

	public static void main(String[] args) throws Exception {
		// String metric = "author_bayesian";
		// String metric = "cf";
		//String metric = "hybrid_title_author_bayesian";
		String metric = "author";
		HitRate hr = new HitRate();
		hr.run(metric);
		/*
		hr.initStmt();
		for (int i = 1; i <= 9; i++) {
			hr.runHybrid(metric, i);
		}
*/
	}

}
